package com.platform.service;

import java.math.BigDecimal;
import java.util.*;

import com.google.common.collect.Maps;
import com.platform.dao.*;
import com.platform.entity.*;
import com.platform.utils.*;

import com.qiniu.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.platform.cache.J2CacheUtils;
import com.platform.util.CommonUtil;


@Service
public class ApiOrderService {
    @Autowired
    private ApiOrderMapper orderDao;
    @Autowired
    private ApiAddressMapper apiAddressMapper;
    @Autowired
    private ApiCartMapper apiCartMapper;
    @Autowired
    private ApiCouponMapper apiCouponMapper;
    @Autowired
    private ApiOrderMapper apiOrderMapper;
    @Autowired
    private ApiOrderGoodsMapper apiOrderGoodsMapper;
    @Autowired
    private ApiProductService productService;
    @Autowired
    private ApiUserService apiUserService;

    @Autowired
    private ApiUserTransactionRecordService apiUserTransactionRecordService;

    @Autowired
    private ApiUserFreezeAccountService apiUserFreezeAccountService;

    @Autowired
    private ApiGoodsSpecificationService goodsSpecificationService;

    @Autowired
    private ApiUserLevelService apiUserLevelService;

    public OrderVo queryObject(Integer id) {
        return orderDao.queryObject(id);
    }

    public OrderVo queryByOrderSn(String orderSn) {
        return orderDao.queryByOrderSn(orderSn);
    }

    public List<OrderVo> queryList(Map<String, Object> map) {
        return orderDao.queryList(map);
    }


    public int queryTotal(Map<String, Object> map) {
        return orderDao.queryTotal(map);
    }


    public void save(OrderVo order) {
        orderDao.save(order);
    }


    public int update(OrderVo order) {
        return orderDao.update(order);
    }


    public void delete(Integer id) {
        orderDao.delete(id);
    }


    public void deleteBatch(Integer[] ids) {
        orderDao.deleteBatch(ids);
    }

    @Transactional
    public R payByAccount(UserVo userVo, OrderVo orderVo){
        if (userVo.getAccount().compareTo(orderVo.getActual_price()) < 0){
            //佣金不够
            return R.error("当前佣金不足，请选择其他支付方式");
        }

        boolean payOK = apiUserService.deductAccount(userVo.getUserId(), orderVo.getActual_price());
        if (!payOK){
            return R.error("当前佣金不足，请选择其他支付方式");
        }

        orderVo.setPay_type(OrderVo.PAY_TYPE_ACCOUNT);
        update(orderVo);
        return payOK(orderVo.getOrder_sn());
    }


    @Transactional
    public Map<String, Object> submit(JSONObject jsonParam, UserVo loginUser) {
        Map<String, Object> resultObj = new HashMap<String, Object>();

        Integer couponId = jsonParam.getInteger("couponId");
        String type = jsonParam.getString("type");
        String postscript = jsonParam.getString("postscript");
//        AddressVo addressVo = jsonParam.getObject("checkedAddress",AddressVo.class);
        AddressVo addressVo = apiAddressMapper.queryObject(jsonParam.getInteger("addressId"));


        Integer freightPrice = 0;

        // * 获取要购买的商品
        List<CartVo> checkedGoodsList = new ArrayList<>();
        //商品总价
        BigDecimal goodsTotalPrice;
        //打折后总价
        BigDecimal actualTotalPrice;


        //判断当前购买人是否直接减去返点
        Map subDiscountInfo = apiUserService.subDiscount(loginUser);
        boolean subDiscount = (boolean)subDiscountInfo.get("subDiscount");
        Long discountUserId = (Long)subDiscountInfo.get("discountUserId");

        BigDecimal discountPrice = BigDecimal.ZERO;


        //商品价格：原来商品实际的卖价 * n
        //订单价格：(商品价格 - 折扣价格) * n + 运费     其中，折扣价格需要根据当前购买人级别，级别为1的折扣价格为0，其余折扣价格为商品折扣价格
        //实际支付：订单价格 - 优惠券
        //折扣价格：商品折扣价格 * n
        //实际折扣价格： 根据当前购买人级别，如果有返点给上级了，实际折扣价格为商品折扣价格，否则为0
        //成本价 = 商品成本价
        //毛利润 = （商品价格 - 商品成本价 - 实际折扣价格） * (购买数量 - 退货数量)

        if (type.equals("cart")) {
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("user_id", loginUser.getUserId());
            param.put("session_id", 1);
            param.put("checked", 1);
            checkedGoodsList = apiCartMapper.queryList(param);
            if (null == checkedGoodsList) {
                resultObj.put("errno", 400);
                resultObj.put("errmsg", "请选择商品");
                return resultObj;
            }
            //统计商品总价
            goodsTotalPrice = new BigDecimal(0.00);
            actualTotalPrice = new BigDecimal(0.00);

            for (CartVo cartItem : checkedGoodsList) {
                //根据当前用户实际情况，计算是否需要减去打折后的单价
                BigDecimal price = subDiscount ? cartItem.getRetail_price().subtract(cartItem.getDiscount_price()) : cartItem.getRetail_price();
                //原有货物折扣
                discountPrice = discountPrice.add(cartItem.getDiscount_price().multiply(new BigDecimal(cartItem.getNumber())));
                //实际需要支付
                actualTotalPrice = actualTotalPrice.add(price.multiply(new BigDecimal(cartItem.getNumber())));
                //原有货物总价
                goodsTotalPrice = goodsTotalPrice.add(cartItem.getRetail_price().multiply(new BigDecimal(cartItem.getNumber())));
            }
        } else {
            BuyGoodsVo goodsVo = (BuyGoodsVo) J2CacheUtils.get(J2CacheUtils.SHOP_CACHE_NAME, "goods" + loginUser.getUserId());
            ProductVo productInfo = productService.queryObject(goodsVo.getProductId());
            //减完折扣后的单价
            BigDecimal price = subDiscount ? productInfo.getRetail_price().subtract(productInfo.getDiscount_price()) : productInfo.getRetail_price();

            discountPrice = productInfo.getDiscount_price().multiply(new BigDecimal(goodsVo.getNumber()));
            actualTotalPrice = price.multiply(new BigDecimal(goodsVo.getNumber()));
            goodsTotalPrice = productInfo.getRetail_price().multiply(new BigDecimal(goodsVo.getNumber()));

            CartVo cartVo = new CartVo();
            BeanUtils.copyProperties(productInfo, cartVo);
            cartVo.setNumber(goodsVo.getNumber());
            cartVo.setProduct_id(goodsVo.getProductId());
            String[] goodsSepcifitionValue = null;
            if (null != productInfo.getGoods_specification_ids() && productInfo.getGoods_specification_ids().length() > 0) {
                Map specificationParam = new HashMap();
                String[] idsArray = productInfo.getGoods_specification_ids().split("_");
                specificationParam.put("ids", idsArray);
                specificationParam.put("goods_id", goodsVo.getGoodsId());
                List<GoodsSpecificationVo> specificationEntities = goodsSpecificationService.queryList(specificationParam);
                goodsSepcifitionValue = new String[specificationEntities.size()];
                for (int i = 0; i < specificationEntities.size(); i++) {
                    goodsSepcifitionValue[i] = specificationEntities.get(i).getValue();
                }
            }
            if (null != goodsSepcifitionValue) {
                cartVo.setGoods_specifition_name_value(StringUtils.join(goodsSepcifitionValue, ";"));
                cartVo.setGoods_specifition_ids(productInfo.getGoods_specification_ids());
            }
            checkedGoodsList.add(cartVo);
        }


        //获取订单使用的优惠券
        BigDecimal couponPrice = new BigDecimal(0.00);
        CouponVo couponVo = null;
        if (couponId != null && couponId != 0) {
            couponVo = apiCouponMapper.getUserCoupon(couponId);
            if (couponVo != null && couponVo.getCoupon_status() == 1) {
                couponPrice = couponVo.getType_money();
            }
        }

        //订单价格计算
        BigDecimal orderTotalPrice = actualTotalPrice.add(new BigDecimal(freightPrice)); //订单的总价

        BigDecimal actualPrice = orderTotalPrice.subtract(couponPrice);  //减去其它支付的金额后，要实际支付的金额

        //
        OrderVo orderInfo = new OrderVo();
        orderInfo.setOrder_sn(CommonUtil.generateOrderNumber());
        orderInfo.setUser_id(loginUser.getUserId());
        //收货地址和运费
        orderInfo.setConsignee(addressVo.getUserName());
        orderInfo.setMobile(addressVo.getTelNumber());
        orderInfo.setCountry(addressVo.getNationalCode());
        orderInfo.setProvince(addressVo.getProvinceName());
        orderInfo.setCity(addressVo.getCityName());
        orderInfo.setDistrict(addressVo.getCountyName());
        orderInfo.setAddress(addressVo.getDetailInfo());
        //
        orderInfo.setFreight_price(freightPrice);
        //留言
        orderInfo.setPostscript(postscript);
        //使用的优惠券
        orderInfo.setCoupon_id(couponId);
        orderInfo.setCoupon_price(couponPrice);
        orderInfo.setAdd_time(new Date());
        orderInfo.setGoods_price(goodsTotalPrice);
        orderInfo.setOrder_price(orderTotalPrice);
        orderInfo.setActual_price(actualPrice);

        orderInfo.setDiscount_price(discountPrice);
        orderInfo.setDiscount_user_id(discountUserId);
        if (discountUserId != null && !discountUserId.equals(loginUser.getUserId())){
            //有目标折扣人且这个人不是当前人自己
            orderInfo.setActual_discount_price(discountPrice);
        } else {
            orderInfo.setActual_discount_price(BigDecimal.ZERO);
        }

        // 待付款
        orderInfo.setOrder_status(0);
        orderInfo.setShipping_status(0);
        orderInfo.setPay_status(0);
        orderInfo.setShipping_id(0);
        orderInfo.setShipping_fee(new BigDecimal(0));
        orderInfo.setIntegral(0);
        orderInfo.setIntegral_money(new BigDecimal(0));
        if (type.equals("cart")) {
            orderInfo.setOrder_type("1");
        } else {
            orderInfo.setOrder_type("4");
        }

        apiOrderMapper.save(orderInfo);
        if (null == orderInfo.getId()) {
            resultObj.put("errno", 1);
            resultObj.put("errmsg", "订单提交失败");
            return resultObj;
        }

        //插入订单信息和订单商品
        List<OrderGoodsVo> orderGoodsData = new ArrayList<OrderGoodsVo>();
        for (CartVo goodsItem : checkedGoodsList) {
            OrderGoodsVo orderGoodsVo = new OrderGoodsVo();
            orderGoodsVo.setOrder_id(orderInfo.getId());
            orderGoodsVo.setGoods_id(goodsItem.getGoods_id());
            orderGoodsVo.setGoods_sn(goodsItem.getGoods_sn());
            orderGoodsVo.setProduct_id(goodsItem.getProduct_id());
            orderGoodsVo.setGoods_name(goodsItem.getGoods_name());
            orderGoodsVo.setList_pic_url(goodsItem.getList_pic_url());
            orderGoodsVo.setMarket_price(goodsItem.getMarket_price());
            orderGoodsVo.setRetail_price(goodsItem.getRetail_price());
            orderGoodsVo.setCost_price(goodsItem.getCost_price());
            orderGoodsVo.setDiscount_price(goodsItem.getDiscount_price());
            if (discountUserId != null && !discountUserId.equals(loginUser.getUserId())){
                orderGoodsVo.setActual_discount_price(goodsItem.getDiscount_price());
            } else {
                orderGoodsVo.setActual_discount_price(BigDecimal.ZERO);
            }
            orderGoodsVo.setNumber(goodsItem.getNumber());
            orderGoodsVo.setGoods_specifition_name_value(goodsItem.getGoods_specifition_name_value());
            orderGoodsVo.setGoods_specifition_ids(goodsItem.getGoods_specifition_ids());
            orderGoodsData.add(orderGoodsVo);
            apiOrderGoodsMapper.save(orderGoodsVo);

            //下单减库存
            R r = productService.decreaseGoodsNumber(goodsItem.getProduct_id(), goodsItem.getNumber());
            if (!r.isOK()){
                throw new ApiRRException(r.errorMessage());
            }
        }



        //清空已购买的商品
        apiCartMapper.deleteByCart(loginUser.getUserId(), 1, 1);
        resultObj.put("errno", 0);
        resultObj.put("errmsg", "订单提交成功");
        //
        Map<String, OrderVo> orderInfoMap = new HashMap<String, OrderVo>();
        orderInfoMap.put("orderInfo", orderInfo);
        //
        resultObj.put("data", orderInfoMap);
        // 优惠券标记已用
        if (couponVo != null && couponVo.getCoupon_status() == 1) {
            couponVo.setCoupon_status(2);
            apiCouponMapper.updateUserCoupon(couponVo);
        }

        ScheduleUtils.orderAutoCancelJob(orderInfo.getId(), orderInfo.getOrder_sn());
        return resultObj;
    }



    @Transactional
    public R payOK(String orderSn){
        OrderVo orderInfo = queryByOrderSn(orderSn);

        if (orderInfo.getPay_status().intValue() == 2){
            return R.ok();
        }

        orderInfo.setPay_status(2);
        orderInfo.setOrder_status(201);
        orderInfo.setShipping_status(0);
        orderInfo.setPay_time(new Date());
        update(orderInfo);


        UserVo userVo = apiUserService.queryObject(orderInfo.getUser_id());
        Map subDiscount = apiUserService.subDiscount(userVo);


        Map param = Maps.newHashMap();
        param.put("order_id", orderInfo.getId());
        List<OrderGoodsVo> orderGoodsVos = apiOrderGoodsMapper.queryList(param);

        UserLevelVo userLevelVo = apiUserLevelService.queryRule();
        int delayDay = JSONObject.parseObject(userLevelVo.getName()).getIntValue("param0");


        for (OrderGoodsVo item : orderGoodsVos) {
            //保存当前支付人交易记录
            UserTransactionRecordVo userTransactionRecordVo = new UserTransactionRecordVo();
            if ((boolean)subDiscount.get("subDiscount")){
                userTransactionRecordVo.setMoney("-" + item.getRetail_price().subtract(item.getActual_discount_price()).multiply(new BigDecimal(item.getNumber())));
            } else {
                userTransactionRecordVo.setMoney("-" + item.getRetail_price().multiply(new BigDecimal(item.getNumber())));
            }
            userTransactionRecordVo.setUser_id(orderInfo.getUser_id());
            userTransactionRecordVo.setTransaction_user_id(orderInfo.getUser_id());
            String type = orderInfo.getPay_type().equals(OrderVo.PAY_TYPE_WX) ? UserTransactionRecordVo.TRANSACTION_TYPE_PAY_WX : UserTransactionRecordVo.TRANSACTION_TYPE_PAY_ACCOUNT;
            userTransactionRecordVo.setType(type);
            userTransactionRecordVo.setRemark(orderInfo.getPay_type_desc() + orderInfo.getOrder_price().toPlainString() + "元");
            userTransactionRecordVo.setOrder_id(item.getOrder_id());
            userTransactionRecordVo.setOrder_goods_id(item.getId());
            apiUserTransactionRecordService.save(userTransactionRecordVo);


            if (orderInfo.getDiscount_user_id() != null
                    && !orderInfo.getDiscount_user_id().equals(orderInfo.getUser_id())
                    && orderInfo.getActual_discount_price().compareTo(BigDecimal.ZERO) > 0){
                //保存折扣交易记录
                userTransactionRecordVo = new UserTransactionRecordVo();
                userTransactionRecordVo.setMoney(orderInfo.getActual_discount_price().toPlainString());
                userTransactionRecordVo.setUser_id(orderInfo.getDiscount_user_id());
                userTransactionRecordVo.setTransaction_user_id(orderInfo.getUser_id());
                userTransactionRecordVo.setType(UserTransactionRecordVo.TRANSACTION_TYPE_REBATES);
                userTransactionRecordVo.setRemark("代购费返点" + orderInfo.getDiscount_price().setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "元");
                userTransactionRecordVo.setOrder_id(item.getOrder_id());
                userTransactionRecordVo.setOrder_goods_id(item.getId());
                apiUserTransactionRecordService.save(userTransactionRecordVo);

                //保存冻结
                UserFreezeAccountVo userFreezeAccountVo = new UserFreezeAccountVo();
                userFreezeAccountVo.setUser_id(orderInfo.getDiscount_user_id());
                userFreezeAccountVo.setAccount(item.getActual_discount_price().multiply(new BigDecimal(item.getNumber())));
                userFreezeAccountVo.setFreeze_end(DateUtils.addDate(new Date(), delayDay));
                userFreezeAccountVo.setOrder_goods_id(Long.valueOf(item.getId()));
                apiUserFreezeAccountService.save(userFreezeAccountVo);
            }

        }


        return R.ok();
    }

    @Transactional
    public R payError(){
        return R.ok();
    }



    public List<OrderVo> queryFansOrderList(Map<String, Object> map) {
        return orderDao.queryFansOrderList(map);
    }


    public int queryFansOrderTotal(Map<String, Object> map) {
        return orderDao.queryFansOrderTotal(map);
    }



}
